﻿using System;
using System.Collections.Generic;
using System.Text;
using Csla;
using System.Data.Odbc;
using MinaspetroLibrary.Configuracoes;
using System.Data;
using Csla.Data;

namespace MinaspetroLibrary.AssociadoPack
{
    [Serializable()]
    public class Socio : BusinessBase<Socio>
    {
		#region Control Properties
		
        [Csla.NotUndoable()]
        private bool _isEmpty = false;

        public bool IsEmpty
        {
            get { return _isEmpty; }
        }
        #endregion

        #region Business Properties and Methods

        private Guid _id = Guid.NewGuid();

        private string _idEndereco = string.Empty;

        private string _idContato = string.Empty;

        private string _idAssociado = string.Empty;

        private string _nomeSocio = string.Empty;

        private string _estadoCivil = string.Empty;

        private DateTime _dataNascimento = DateTime.Now;

        private string _naturalidade = string.Empty;

        [System.ComponentModel.DataObjectField(true, true)]
        public Guid Id
        {
            get
            {
                CanReadProperty("Id", true);
                return _id;
            }
        }

        public string IdEndereco
        {
            get
            {
                CanReadProperty("idEndereco", true);
                return _idEndereco;
            }
            set
            {
                CanWriteProperty("idEndereco", true);
                if (value == null) value = string.Empty;
                if (!_idEndereco.Equals(value))
                {
                    _idEndereco = value;
                    PropertyHasChanged("idEndereco");
                }
            }
        }

        public string IdContato
        {
            get
            {
                CanReadProperty("IdContato", true);
                return _idContato;
            }
            set
            {
                CanWriteProperty("IdContato", true);
                if (value == null) value = string.Empty;
                if (!_idContato.Equals(value))
                {
                    _idContato = value;
                    PropertyHasChanged("IdContato");
                }
            }
        }

        

        public string IdAssociado
        {
            get
            {
                CanReadProperty("IdAssociado", true);
                return _idAssociado;
            }
            set
            {
                CanWriteProperty("IdAssociado", true);
                if (value == null) value = string.Empty;
                if (!_idAssociado.Equals(value))
                {
                    _idAssociado = value;
                    PropertyHasChanged("IdAssociado");
                }
            }
        }

        public string NomeSocio
        {
            get
            {
                CanReadProperty("NomeSocio", true);
                return _nomeSocio;
            }
            set
            {
                CanWriteProperty("NomeSocio", true);
                if (value == null) value = string.Empty;
                if (!_nomeSocio.Equals(value))
                {
                    _nomeSocio = value;
                    PropertyHasChanged("NomeSocio");
                }
            }
        }

        public string EstadoCivil
        {
            get
            {
                CanReadProperty("EstadoCivil", true);
                return _estadoCivil;
            }
            set
            {
                CanWriteProperty("EstadoCivil", true);
                if (value == null) value = string.Empty;
                if (!_estadoCivil.Equals(value))
                {
                    _estadoCivil = value;
                    PropertyHasChanged("EstadoCivil");
                }
            }
        }

        public DateTime DataNascimento
        {
            
            get
            {
                CanReadProperty("DataNascimento", true);
                return _dataNascimento;
            }
            set
            {
                CanWriteProperty("DataNascimento", true);
                if (!_dataNascimento.Equals(value))
                {
                    _dataNascimento = value;
                    PropertyHasChanged("DataNascimento");
                }
            }
            
        }

        public string DataContratoBandeiraShortString
        {
            get
            {
                CanReadProperty("DataNascimento", true);
                return _dataNascimento.ToString("dd/MM/yyyy");
            }
        }

        public string DataContratoBandeiraFullString
        {
            get
            {
                CanReadProperty("DataNascimento", true);
                return _dataNascimento.ToString("dd/MM/yyyy HH:mm");
            }
        }

        public string Naturalidade
        {
            get
            {
                CanReadProperty("Naturalidade", true);
                return _naturalidade;
            }
            set
            {
                CanWriteProperty("Naturalidade", true);
                if (value == null) value = string.Empty;
                if (!_naturalidade.Equals(value))
                {
                    _naturalidade = value;
                    PropertyHasChanged("Naturalidade");
                }
            }
        }

        protected override object GetIdValue()
        {
            return _id.ToString();
        }

        #endregion //Business Properties and Methods

        #region Validation Rules
        private void AddCustomRules()
        {
            //add custom/non-generated rules here...
        }

        private void AddCommonRules()
        {
        }

        protected override void AddBusinessRules()
        {
            AddCommonRules();
            AddCustomRules();
        }
        #endregion //Validation Rules

        #region Authorization Rules
        protected override void AddAuthorizationRules()
        {
            //TODO: Define authorization rules in Socio
        }


        public static bool CanGetObject()
        {
            return true;
        }

        public static bool CanAddObject()
        {
            return true;
        }

        public static bool CanEditObject()
        {
            return true;
        }

        public static bool CanDeleteObject()
        {
            return true;
        }
        #endregion //Authorization Rules

        #region Factory Methods
        private Socio()
        { /* require use of factory method */ }

        public static Socio NewSocio()
        {
            if (!CanAddObject())
                throw new System.Security.SecurityException("Usuário não autorizado a adicionar Socio");
            return DataPortal.Create<Socio>();
        }

        public static Socio GetSocio(Guid id)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar Socio");
            return DataPortal.Fetch<Socio>(new Criteria(id));
        }

        public static Socio GetSocioByAssoc(Guid id)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("Usuário não autorizado a visualizar Socio por ID do associado");
            return DataPortal.Fetch<Socio>(new Criteria(id, id));
        }

        public override Socio Save()
        {
            if (IsDeleted && !CanDeleteObject())
                throw new System.Security.SecurityException("Usuário não autorizado a remover Socio");
            else if (IsNew && !CanAddObject())
                throw new System.Security.SecurityException("Usuário não autorizado a adicionar Socio");
            else if (!CanEditObject())
                throw new System.Security.SecurityException("Usuário não autorizado a atualizar Socio");
            return base.Save();
        }

        public static void DeleteSocio(Guid id)
        {
            if (!CanDeleteObject())
                throw new System.Security.SecurityException("Usuário não autorizado a remover Socio");
            DataPortal.Delete(new Criteria(id));
        }

        #endregion //Factory Methods

        #region Data Access

        #region Criteria

        [Serializable()]
        private class Criteria
        {
            public Guid Id;
            public Guid IdAssoc;

            public Criteria(Guid Id)
            {
                this.Id = Id;

            }

            public Criteria(Guid Id, Guid IdAssoc)
            {
                this.Id = Guid.Empty;
                this.IdAssoc = IdAssoc;
            }
        }


        #endregion //Criteria

        #region Data Access - Create
        [RunLocal]
        protected override void DataPortal_Create()
        {
            _isEmpty = false;
            ValidationRules.CheckRules();
        }

        #endregion //Data Access - Create

        #region Data Access - Fetch
        private void DataPortal_Fetch(Criteria criteria)
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();
                ExecuteFetch(cn, criteria);
            }//using
        }

        private void ExecuteFetch(OdbcConnection cn, Criteria criteria)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetFetchScript(criteria);
                using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
                {
                    FetchObject(dr);
                    ValidationRules.CheckRules();
                    FetchChildren(dr);
                }
            }//using
        }

        private string GetFetchScript(Criteria criteria)
        {
            string query = "SELECT "
                 + "Id, "
                 + "IdContato, "
                 + "IdEndereco, "
                 + "IdAssociado, "
                 + "NomeSocio, "
                 + "DataNascimento, "
                 + "EstadoCivil, "
                 + "Naturalidade "
                 + "FROM sociotb ";
            if (Guid.Empty.Equals(criteria.Id))
                query += "WHERE IdAssociado=\"" + criteria.IdAssoc.ToString() + "\";";
            else
                 query += "WHERE Id=\"" + criteria.Id.ToString() + "\";";
            return query;
        }

        private void FetchObject(SafeDataReader dr)
        {
            _isEmpty = !dr.Read();
            if (_isEmpty) return;

            _id = new Guid(dr["Id"].ToString());
            _idEndereco = dr.GetString("IdEndereco");
            _idContato = dr.GetString("IdContato");
            _idAssociado = dr.GetString("IdAssociado");
            _nomeSocio = dr.GetString("NomeSocio");
            _estadoCivil = dr.GetString("EstadoCivil");
            _dataNascimento = dr.GetDateTime("DataNascimento");
            _naturalidade = dr.GetString("Naturalidade");
        }

        private void FetchChildren(SafeDataReader dr)
        {
        }
        #endregion //Data Access - Fetch

        #region Data Access - Insert
        protected override void DataPortal_Insert()
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();
                ExecuteInsert(cn);
                UpdateChildren(cn);
            }
            MinaspetroLibrary.UsuarioPack.Usuario.UsuarioInSession.AtualizarHitorico("Insert - Sociotb - Id: " + _id.ToString());
        }

        private void ExecuteInsert(OdbcConnection cn)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetInsertScript();

                cm.ExecuteNonQuery();
                
            }//using
        }

        private string GetInsertScript()
        {
            return "INSERT INTO Sociotb "
                + "( Id, IdAssociado, idEndereco, IdContato, NomeSocio, EstadoCivil, DataNascimento, Naturalidade ) "
                + " VALUES (\""
                + _id.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _idAssociado.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _idEndereco.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _idContato.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _nomeSocio.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _estadoCivil.ToString().Trim().Replace("\"", "\\\"") + "\", \""
                + _dataNascimento.ToString("yyyy-MM-dd HH:mm:ss") + "\", \""
                + _naturalidade.ToString().Trim().Replace("\"", "\\\"") + "\")";
        }
        #endregion //Data Access - Insert

        #region Data Access - Update
        protected override void DataPortal_Update()
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();

                if (base.IsDirty)
                {
                    ExecuteUpdate(cn);
                }

                //update child object(s)
                UpdateChildren(cn);
            }//using
            MinaspetroLibrary.UsuarioPack.Usuario.UsuarioInSession.AtualizarHitorico("Update - Sociotb - Id: " + _id.ToString());
        }

        private void ExecuteUpdate(OdbcConnection cn)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = GetUpdateScript();

                if (cm.ExecuteNonQuery() == 0)
                    throw new Exception("Este registro foi editado por outro usuario.");
            }//using
        }

        private string GetUpdateScript()
        {
            return "Update sociotb set "
                    + "idEndereco=\"" + _idEndereco.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "IdAssociado=\"" + _idAssociado.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "IdContato=\"" + _idContato.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "NomeSocio=\"" + _nomeSocio.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "EstadoCivil=\"" + _estadoCivil.ToString().Trim().Replace("\"", "\\\"") + "\", "
                    + "DataNascimento=\"" + _dataNascimento.ToString("yyyy-MM-dd HH:mm:ss") + "\", "
                    + "Naturalidade=\"" + _naturalidade.ToString().Trim().Replace("\"", "\\\"") + "\";";
        }

        private void UpdateChildren(OdbcConnection cn)
        {
        }
        #endregion //Data Access - Update

        #region Data Access - Delete
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(new Criteria(_id));
        }

        private void DataPortal_Delete(Criteria criteria)
        {
            using (OdbcConnection cn = new OdbcConnection(ConfigDatabase.MinaspetroConnection))
            {
                cn.Open();

                ExecuteDelete(cn, criteria);

            }//using
            MinaspetroLibrary.UsuarioPack.Usuario.UsuarioInSession.AtualizarHitorico("Delete - Sociotb - Id: " + _id.ToString());
        }

        private void ExecuteDelete(OdbcConnection cn, Criteria criteria)
        {
            using (OdbcCommand cm = cn.CreateCommand())
            {
                cm.CommandType = CommandType.Text;
                cm.CommandText = cm.CommandText = "DELETE from sociotb WHERE Id=\"" + criteria.Id.ToString().Trim().Replace("\"", "\\\"") + "\";";

                cm.ExecuteNonQuery();
            }//using
        }
        #endregion //Data Access - Delete
        #endregion //Data Access
    }
}